import React, { useState } from "react";
import {
  Button,
  Card,
  Typography,
  Form,
  Input,
  Upload,
  Select,
  InputNumber,
  Space,
  message,
  Alert,
  Divider,
  Tag,
  List,
  Progress,
  Tooltip,
  ConfigProvider,
  Switch,
} from "antd";
import { PlusOutlined, CloseOutlined } from "@ant-design/icons";
import type { UploadFile, UploadProps } from "antd/es/upload/interface";
import SteppedModal from "../components/SteppedModal";
import ImageDisplay from "../components/ImageDisplay";
import type { StepConfig } from "../components/SteppedModal";
import useFileUtils from "../hooks/useFileUtils";
import "./styles/FileUploadDemo.less";
import Icon from "@/utils/icons";
import InfoTooltipIcon from "@/components/InfoTooltipIcon";

const { Title, Paragraph, Text } = Typography;
const { Dragger } = Upload;
const { Option } = Select;
const { TextArea } = Input;

const FileUploadDemo: React.FC = () => {
  const [visible, setVisible] = useState(false);
  const [uploadForm] = Form.useForm();
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [uploading, setUploading] = useState(false);
  const { getFileIcon, formatFileSize } = useFileUtils();
  const [inputValue, setInputValue] = useState(""); // 移到组件顶部

  // 分段策略
  const [segmentStrategy, setSegmentStrategy] = useState("auto"); // auto or custom
  const [segmentIdentifierOptions, setSegmentIdentifierOptions] = useState([
    { label: "换行", value: "换行", type: "default" },
    { label: "句号", value: "句号" },
    { label: "问号", value: "问号" },
    { label: "分号", value: "分号" },
    { label: "感叹号", value: "感叹号" },
  ]);
  // 上传配置
  const uploadProps: UploadProps = {
    name: "file",
    multiple: true, // 支持多文件上传
    fileList,
    showUploadList: false, // 隐藏默认的文件列表
    accept:
      ".docx,.xlsx,.xls,.ppt,.pptx,.pdf,.txt,.jpeg,.jpg,.png,.tif,.tiff,.gif,.csv", // 限制文件类型
    beforeUpload: (file) => {
      // 检查文件数量限制
      if (fileList.length >= 15) {
        message.error("最多只能上传15个文件!");
        return Upload.LIST_IGNORE;
      }

      // 检查文件大小限制 (100MB)
      const isLt100M = file.size / 1024 / 1024 < 100;
      if (!isLt100M) {
        message.error("文件大小不能超过 100MB!");
        return Upload.LIST_IGNORE;
      }

      // 验证文件类型
      const fileName = file.name.toLowerCase();
      const validExtensions = [
        ".docx",
        ".xlsx",
        ".xls",
        ".ppt",
        ".pptx",
        ".pdf",
        ".txt",
        ".jpeg",
        ".jpg",
        ".png",
        ".tif",
        ".tiff",
        ".gif",
        ".csv",
      ];

      const isValidFileType = validExtensions.some((ext) =>
        fileName.endsWith(ext)
      );
      if (!isValidFileType) {
        message.error(
          "只支持 DOCX、XLSX、XLS、PPT、PDF、TXT、JPEG、JPG、PNG、TIF、GIF、CSV 格式的文件!"
        );
        return Upload.LIST_IGNORE;
      }

      // 添加到文件列表
      setFileList((prevList) => [...prevList, file]);
      return false; // 阻止自动上传
    },
    onRemove: (file) => {
      // 从列表中移除指定文件
      setFileList((prevList) =>
        prevList.filter((item) => item.uid !== file.uid)
      );
    },
  };

  // 自定义文件列表组件
  const CustomFileList = () => {
    if (fileList.length === 0) return null;

    return (
      <div className="file-list-container">
        {/* {fileList.length > 0 && (
          <div className="file-list-header">
            <span>已选择 {fileList.length}/15 个文件</span>
            <Button
              type="text"
              onClick={() => setFileList([])}
              disabled={uploading}
            >
              清空全部
            </Button>
          </div>
        )} */}
        <List
          className="file-list"
          itemLayout="horizontal"
          dataSource={fileList}
          split={false}
          renderItem={(file) => (
            <List.Item className="file-list-item">
              <div className="file-item-content">
                {getFileIcon(file.type || "")}
                <div className="file-info">
                  <div className="file-name" title={file.name}>
                    {file.name}
                  </div>
                  <div className="file-meta">
                    <span className="file-size">
                      {formatFileSize(file.size || 0)}
                    </span>
                    <span className="file-type">{file.type || "未知类型"}</span>
                  </div>
                </div>
                <Tooltip title="删除文件">
                  <Button
                    type="text"
                    icon={<CloseOutlined />}
                    onClick={(e) => {
                      // 阻止事件冒泡，避免触发其他点击事件
                      e.stopPropagation();
                      // 创建新的文件列表，排除当前文件
                      const newFileList = fileList.filter(
                        (item) => item.uid !== file.uid
                      );
                      // 更新状态
                      setFileList(newFileList);
                      // 如果删除后列表为空，重置表单相关字段
                      if (newFileList.length === 0) {
                        uploadForm.setFieldsValue({ files: undefined });
                      }
                    }}
                    disabled={uploading}
                  />
                </Tooltip>
              </div>
            </List.Item>
          )}
        />
      </div>
    );
  };

  // 分段策略的InfoTooltip
  const segmentStrategyTooltip = (
    <div style={{ fontSize: "13px", lineHeight: 1.7 }}>
      <div style={{ color: "#FFFFFF", marginBottom: 4 }}>
        <div style={{ marginBottom: 4 }}>
          内容分段能更精准定位关键信息，让 AI 更好地“理解”和“提取”知识。
        </div>
        <div>
          在将文档添加到知识库前，需先将内容切块并转化为向量（embedding），进入“语义空间”。分块决定每个向量能表达的语义范围，是
          AI 能否准确理解和检索的关键。
        </div>
      </div>
      <div>
        <div style={{ marginBottom: 4 }}>
          如果分块太大，可能包含太多不相关的信息，从而降低了检索的准确性。
        </div>
        <div style={{ marginBottom: 4 }}>
          <Icon name="Embedding" width={286} height={128} />
        </div>
        <div style={{ marginBottom: 4 }}>
          如果分块太小可能会丢失必要的上下文信息，导致生成的响应缺乏连贯性或深度。
        </div>
        <div>
          <Icon name="Embedding2" width={286} height={128} />
        </div>
      </div>
    </div>
  );

  const segmentIdentifierTooltip = () => {
    const blockStyle = {
      display: "inline-block",
      paddingRight: 4,
      paddingLeft: 4,
      fontSize: 10,
      borderRadius: 2,
      backgroundColor: "rgba(45, 212, 192, 0.1)",
      marginRight: 2,
      marginLeft: 2,
      height: 15,
      lineHeight: "15px",
    };
    return (
      <div style={{ fontSize: "13px", lineHeight: 1.7 }}>
        <div style={{ color: "#FFFFFF", marginBottom: 4 }}>
          <div style={{ marginBottom: 4 }}>
            分段标识符是文档中的特定符号（如句号、逗号、换行符），用于将长文本自动切割成独立段落，方便AI理解和检索。
          </div>
        </div>
        <div>
          <div style={{ marginBottom: 4 }}>
            如果不进行设置，会自动利用
            <span style={blockStyle}>换行</span>
            <span style={blockStyle}>句号</span>
            <span style={blockStyle}>问号</span>
            <span style={blockStyle}>感叹号</span>
            等标点符号作为分段依据。
          </div>
        </div>
      </div>
    );
  };

  // 分段长度说明
  const segmentLengthTooltip = () => (
    <div style={{ fontSize: "13px", lineHeight: 1.7 }}>
      <div style={{ color: "#FFFFFF", marginBottom: 4 }}>
        <div style={{ marginBottom: 4 }}>
          分段长度是每个文本块的最大长度，用以控制内容切割的粗细。
        </div>
      </div>
      <div style={{ marginBottom: 4 }}>
        <div>
          设置分段最大长度能够确保每个段落的信息量适中，便于理解和分析；可以防止段落过长，导致后续处理（如检索、匹配）的效率降低。
        </div>
        <div>建议根据内容类型灵活调整，平衡信息完整性与处理效率： </div>
      </div>

      <div>
        <ImageDisplay
          fileName="SegmentLength.png"
          width="100%"
          height="auto"
          altText="分段标识符示例"
        />
      </div>
    </div>
  );

  const structuredLayoutTooltip = () => (
    <div style={{ fontSize: "13px", lineHeight: 1.7 }}>
      <div style={{ color: "#FFFFFF", marginBottom: 4 }}>
        <div style={{ marginBottom: 4 }}>
          开启后，系统将自动识别文档中的布局结构（如标题、段落、表格、列表等），以更准确地提取内容和上下文关系，提高解析质量。
        </div>
      </div>
      <div style={{ marginBottom: 4 }}>
        <div>
          <div>
            适用于格式复杂或结构清晰的文档，请根据文档情况选择是否开启。
          </div>
        </div>
      </div>
    </div>
  );
  const formItemlabel = (
    label?: string,
    mainContent?: React.ReactNode,
    tooltipWidth = 410
  ) => {
    const style = {
      display: "flex",
      alignItems: "center",
      gap: "4px",
    };
    return (
      <div style={style}>
        {label}
        <InfoTooltipIcon
          iconColor="rgba(18, 18, 18, 0.5)"
          mainContent={mainContent}
          tooltipWidth={tooltipWidth}
        />
      </div>
    );
  };
  // 两个步骤的配置
  const steps: StepConfig[] = [
    {
      title: "选择文件",
      content: (
        <Form form={uploadForm} layout="vertical" requiredMark="optional">
          <Form.Item
            name="files"
            rules={[{ required: true, message: "请选择要上传的文件" }]}
            style={{ marginBottom: 16 }}
          >
            <Dragger {...uploadProps} className="file-upload-dragger">
              <div className="ant-upload-drag-icon">
                <Icon name="Upload" size={32} />
              </div>
              <div className="ant-upload-text">点击或拖拽文件到此区域上传</div>

              <div className="ant-upload-hint">
                支持DOCX、XLSX、XLS、PPT、PDF、TXT、JPEG、JPG、PNG、TIF、GIF、CSV
              </div>
              <div className="ant-upload-hint">
                最多支持15个文件，每个文件不能超过 100 MB
              </div>
            </Dragger>
          </Form.Item>

          {/* 自定义文件列表 */}
          <CustomFileList />
        </Form>
      ),
      // 如果没有选择文件，禁用下一步按钮
      nextDisabled: fileList.length === 0,
    },

    {
      title: "参数设置",
      content: (
        <ConfigProvider
          theme={{
            components: {
              Form: {
                labelColor: "rgba(18, 18, 18, 0.7)",
              },
            },
          }}
        >
          <div className="file-upload-params">
            {/* 分段策略 */}
            <div className="file-upload-params-title">
              分段策略
              <InfoTooltipIcon
                mainContent={segmentStrategyTooltip}
                tooltipWidth={310}
              />
            </div>
            {/* 分段策略选择 */}
            <div
              className={
                "file-upload-params-item" +
                (segmentStrategy === "auto" ? " selected" : "")
              }
              onClick={() => setSegmentStrategy("auto")}
            >
              <div className="file-upload-params-item-label">
                自动分段与清洗
              </div>
              <div className="file-upload-params-item-value">
                使用系统默认的参数和规则
              </div>
            </div>

            <div
              className={
                "file-upload-params-item" +
                (segmentStrategy === "custom" ? " selected" : "")
              }
              onClick={() => setSegmentStrategy("custom")}
            >
              <div className="file-upload-params-item-label">自定义</div>
              <div className="file-upload-params-item-value">
                自定义分段规则、长度、是否结构化布局
              </div>
              {/* 其他参数 */}
              {segmentStrategy === "custom" && (
                <div className="file-upload-params-item-custom ">
                  <Form
                    form={uploadForm}
                    layout="vertical"
                    requiredMark="optional"
                  >
                    <Form.Item
                      label={formItemlabel(
                        "分段标识符",
                        segmentIdentifierTooltip()
                      )}
                      name="segmentIdentifier"
                      initialValue={["换行", "句号", "问号", "感叹号"]}
                      rules={[{ required: true, message: "请选择分段标识符" }]}
                    >
                      <Select
                        mode="multiple"
                        options={segmentIdentifierOptions}
                        placeholder="请选择或输入分段标识符"
                        style={{ width: "100%" }}
                        optionLabelProp="label"
                        dropdownRender={(menu) => {
                          const [error, setError] = useState(""); // 错误信息状态

                          const addOption = () => {
                            if (!inputValue.trim()) {
                              setError("输入不能为空！");
                              return;
                            }
                            if (/[\u4e00-\u9fa5]/.test(inputValue.trim())) {
                              setError("选项不能包含中文字符！");
                              return;
                            }
                            if (
                              segmentIdentifierOptions.some(
                                (opt) => opt.value === inputValue.trim()
                              )
                            ) {
                              setError("选项已存在，不能重复添加！");
                              return;
                            }
                            setSegmentIdentifierOptions((prev) => [
                              ...prev,
                              {
                                label: inputValue.trim(),
                                value: inputValue.trim(),
                                type: "custom",
                              },
                            ]);
                            setInputValue("");
                            setError(""); // 清除错误信息
                          };

                          return (
                            <div>
                              {menu}
                              <Divider style={{ margin: "8px 0" }} />
                              <div
                                style={{ padding: "8px", marginBottom: "8px" }}
                              >
                                <div
                                  style={{
                                    display: "flex",
                                    gap: "8px",
                                  }}
                                >
                                  <Input
                                    style={{
                                      flex: "auto",
                                      borderColor: error ? "red" : undefined,
                                    }}
                                    value={inputValue}
                                    onChange={(e) => {
                                      setInputValue(e.target.value);
                                      setError(""); // 清除错误信息
                                    }}
                                    placeholder="输入自定义标识符"
                                  />
                                  <Button
                                    type="text"
                                    style={{
                                      width: "140px",
                                    }}
                                    onClick={addOption}
                                    icon={<PlusOutlined />}
                                  >
                                    添加选项
                                  </Button>
                                </div>

                                {error && (
                                  <div
                                    style={{ color: "red", marginTop: "4px" }}
                                  >
                                    {error}
                                  </div>
                                )}
                              </div>
                            </div>
                          );
                        }}
                        optionRender={(option, { index }) => (
                          <div
                            onClick={(e) => {
                              // e.stopPropagation(); // 阻止事件冒泡
                              console.log("选中选项:", option);
                            }}
                            style={{
                              position: "absolute",
                              left: 0,
                              right: 0,
                              padding: "0px 12px",
                              display: "flex",
                              justifyContent: "space-between",
                              alignItems: "center",
                            }}
                          >
                            <span>{option.label}</span>
                            {option.data?.type === "custom" && (
                              <Button
                                type="text"
                                danger
                                size="small"
                                onClick={(e) => {
                                  e.stopPropagation(); // 阻止事件冒泡
                                  setSegmentIdentifierOptions((prev) =>
                                    prev.filter(
                                      (opt) => opt.value !== option.value
                                    )
                                  );
                                }}
                              >
                                <CloseOutlined />
                              </Button>
                            )}
                          </div>
                        )}
                      />
                    </Form.Item>

                    <Form.Item
                      name="segmentLength"
                      label={formItemlabel(
                        "分段长度",
                        segmentLengthTooltip(),
                        600
                      )}
                      rules={[
                        { required: true, message: "请输入分段长度" },
                        {
                          type: "number",
                          min: 100,
                          max: 800,
                          message: "分段长度必须在 100 到 800 之间",
                        },
                      ]}
                      initialValue={128} // 默认值
                    >
                      <InputNumber
                        placeholder="请输入分段长度"
                        style={{
                          width: 130,
                        }}
                        suffix="tokens" // 单位
                        min={100} // 最小值
                        max={800} // 最大值
                        step={1} // 最小刻度
                      />
                    </Form.Item>

                    <Form.Item
                      name="structuredLayout"
                      initialValue={true} // 默认开启
                      valuePropName="checked"
                    >
                      <Switch size="small" style={{ marginRight: 8 }}></Switch>

                      {formItemlabel(
                        "识别文档的结构化布局",
                        structuredLayoutTooltip(),
                        330
                      )}
                    </Form.Item>
                  </Form>
                </div>
              )}
            </div>
          </div>
        </ConfigProvider>
      ),
    },
  ];

  // 处理步骤切换
  const handleStepChange = (current: number, next: number) => {
    // 第一步到第二步：验证是否已选择文件
    if (current === 0 && next === 1) {
      if (fileList.length === 0) {
        message.error("请先选择要上传的文件");
        return false;
      }
      return true;
    }
    return true;
  };

  // 打开对话框
  const showModal = () => {
    setVisible(true);
    setFileList([]);
    uploadForm.resetFields();
  };

  // 关闭对话框
  const handleCancel = () => {
    setVisible(false);
    setFileList([]);
  };

  // 处理上传完成
  const handleFinish = async () => {
    try {
      // 验证表单
      await uploadForm.validateFields();

      // 模拟上传
      setUploading(true);

      // 获取表单数据
      const values = uploadForm.getFieldsValue();

      // 创建FormData对象
      const formData = new FormData();
      fileList.forEach((file, index) => {
        // 对每个文件使用不同的名称
        formData.append(`file-${index}`, file as any);
      });

      // 添加文件数量信息
      formData.append("fileCount", fileList.length.toString());

      // 添加其他参数
      Object.keys(values).forEach((key) => {
        if (key !== "files" && values[key] !== undefined) {
          if (key === "tags" && Array.isArray(values[key])) {
            formData.append(key, JSON.stringify(values[key]));
          } else {
            formData.append(key, values[key]);
          }
        }
      });

      // 模拟API请求
      setTimeout(() => {
        setUploading(false);
        message.success(`成功上传 ${fileList.length} 个文件！`);
        console.log("上传数据:", {
          files: fileList,
          params: values,
        });
        setVisible(false);
      }, 1500);
    } catch (error) {
      console.error("表单验证失败:", error);
    }
  };

  return (
    <div className="file-upload-demo">
      <Title level={2}>文件上传</Title>
      <Paragraph>
        使用步骤式对话框实现的文件上传功能，分为选择文件和设置参数两个步骤。
      </Paragraph>

      <Card className="demo-card">
        <Space direction="vertical" size="large" style={{ width: "100%" }}>
          <div>
            <Title level={4}>文件上传示例</Title>
            <Paragraph>
              这个示例演示了如何使用步骤式对话框组件来实现文件上传流程，包括文件选择和参数设置两个步骤。
            </Paragraph>
            <Button type="primary" onClick={showModal}>
              上传文件
            </Button>
          </div>

          <Divider />

          <div>
            <Title level={5}>支持的功能</Title>
            <Space size={[8, 16]} wrap>
              <Tag color="blue">文件选择</Tag>
              <Tag color="green">文件预览</Tag>
              <Tag color="purple">参数设置</Tag>
              <Tag color="orange">权限控制</Tag>
              <Tag color="cyan">标签分类</Tag>
            </Space>
          </div>
        </Space>
      </Card>

      {/* 文件上传对话框 */}
      <SteppedModal
        className="file-upload-modal"
        title="文件上传"
        visible={visible}
        onCancel={handleCancel}
        onFinish={handleFinish}
        steps={steps}
        onStepChange={handleStepChange}
        finishText={uploading ? "上传中..." : "开始上传"}
        nextText="下一步"
        prevText="上一步"
      />
    </div>
  );
};

export default FileUploadDemo;
